/**
 * <copyright> Copyright (c) 2011-2012
 */
package seteam12;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;

/**
 * This singleton class represents an extensible framework for games using Java's Swing as their graphical appearance.
 * This framework enables the user to choose from a set of games and start/stop them as he wishes to. Developers can
 * easily extend this framework by adding new games using {@link #registerGame(String, Class)}. Any registered game will
 * appear in a combo box for the user to select it. After all games have been registered, the framework should be
 * started using {@link #start()}.
 */
public final class GameFramework extends JFrame {

	private static final long serialVersionUID = -6375217633014229161L;

	private static GameFramework instance = new GameFramework();

	private Map<String, String> games = new HashMap<String, String>(2);

	private GameInterface currentGame;

	private GameFramework() {
		super("Cogafra");
	}

	/**
	 * Registers a game by adding the game's name and the corresponding {@link JFrame} to the list of games visible to
	 * the user.
	 * 
	 * @param gameName the name of the game visible to the user
	 * @param gameClass the class to instantiate when starting the game
	 */
	public void registerGame(String gameName, String gameClass) {
		games.put(gameName, gameClass);
	}

	/**
	 * @return the singleton {@link GameFramework} instance.
	 */
	public static GameFramework getInstance() {
		return instance;
	}

	/**
	 * <p>
	 * Initializes the framework by adding the graphical components and opening the frame.
	 * </p>
	 * <p>
	 * <b>Note:</b> All games have to be registered <b>before</b> calling this method. Otherwise they won't appear in
	 * the combo box.
	 * </p>
	 */
	public void start() {
		Object[] gameNames = games.keySet().toArray();
		final JComboBox combo = new JComboBox(gameNames);

		JButton startButton = new JButton("Start Game");
		startButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				//Class<? extends JFrame> game = games.get(combo.getSelectedItem());
				System.out.println(games.get(combo.getSelectedItem()));
				Class c = null;
				try {
					c = Thread.currentThread().getContextClassLoader().loadClass(games.get(combo.getSelectedItem()));
				} catch (ClassNotFoundException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			
				if(GameInterface.class.isAssignableFrom(c)) {
					try {
						if(c!=null) currentGame = (GameInterface) c.newInstance();
						currentGame.startGame();
					} catch (InstantiationException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					} catch (IllegalAccessException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					
				}
				
			}
		});

		JButton stopButton = new JButton("Stop Game");
		stopButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				currentGame.stopGame();
				currentGame = null;
			}

		});

		add(combo, BorderLayout.NORTH);
		add(startButton, BorderLayout.CENTER);
		add(stopButton, BorderLayout.SOUTH);

		setResizable(false);
		setSize(225, 105);
		setLocation(200, 250);

		setDefaultCloseOperation(EXIT_ON_CLOSE);

		setVisible(true);
	}

//	private void startGame(Class<? extends JFrame> game) {
//		try {
//			stopGame();
//			currentGame = game.getConstructor().newInstance();
//			currentGame.setVisible(true);
//		} catch (IllegalArgumentException e) {
//			e.printStackTrace();
//		} catch (SecurityException e) {
//			e.printStackTrace();
//		} catch (InstantiationException e) {
//			e.printStackTrace();
//		} catch (IllegalAccessException e) {
//			e.printStackTrace();
//		} catch (InvocationTargetException e) {
//			e.printStackTrace();
//		} catch (NoSuchMethodException e) {
//			e.printStackTrace();
//		}
//	}

//	private void stopGame() {
//		if (currentGame != null) {
//			currentGame.dispose();
//			currentGame = null;
//		}
//	}

}
